<?php

namespace app\admin\service;

use app\admin\service\statistics\completions\TimesCompletion;
use app\admin\service\statistics\datatable\AbstractComputeStatistician;
use app\admin\service\statistics\datatable\AbstractQueryStatistician;
use app\admin\service\statistics\datatable\Provider;
use app\admin\service\statistics\filters\TimeFilter;
use app\admin\service\statistics\groupers\DateGrouper;
use app\common\model\AccessLog;
use app\common\model\Consulting;
use app\common\model\LawCase;
use app\common\model\Lawsuit;
use app\common\model\Member;
use app\common\model\Trade;
use ShidianUtil\Utils\TimeUtil;
use think\facade\Config;

/**
 * 核销板块数据日报
 * Class LinkTableService
 * @package app\admin\service
 */
class DataTableService
{

    private array $cache = [];

    /**
     * 核心版块数据日报表统计
     * @param $startTime
     * @param $endTime
     * @return array
     */
    public function index($startTime, $endTime)
    {

        $timeList = TimeUtil::timeList(TimeUtil::DAY, $startTime, $endTime, true);

        $days = [];
        foreach ($timeList as $item) {
            $s = $item['s_time'];
            $days[] = ['name' => date('j', $s) . '日'];
        }

        $fields = Config::get('datatable', []);

        $list = [];
        foreach ($fields as $field) {
            $list[] = [
                'name' => $field['title'],
                'datas' => $this->indexOfDataTable($field['implClass'], $startTime, $endTime),
            ];
        }

        return [
            'day_count' => count($days),
            'days' => $days,
            'list' => $list,
        ];
    }

    /**
     * 统计单个字段
     * @param $implClass
     * @param $startTime
     * @param $endTime
     * @return array
     */
    private function indexOfDataTable($implClass, $startTime, $endTime)
    {

        $times = TimeUtil::timeList(TimeUtil::DAY, $startTime, $endTime, true);

        $timeFilter = new TimeFilter($startTime, $endTime);

        $dateGrouper = new DateGrouper();

        $timesCompletion = new TimesCompletion($times);

        // 过滤
        $filters = [$timeFilter];

        // 分组
        $groupers = [$dateGrouper];

        // 补齐
        $completions = [$timesCompletion];

        return $this->getData($implClass, $filters, $groupers, $completions);
    }

    /**
     * 获取结果
     * @param $implClass
     * @param $filters
     * @param $groupers
     * @param $completions
     * @return array
     */
    private function getData($implClass, $filters, $groupers, $completions): array
    {
        // 缓存
        if (!isset($this->cache[$implClass])) {

            $impl = new $implClass();

            if ($impl instanceof AbstractQueryStatistician) {

                // 设置筛选
                if (!empty($filters)) {
                    $impl->setFilters(...$filters);
                }

                // 设置分组统计
                if (!empty($groupers)) {
                    $impl->setGroupers(...$groupers);
                }

                // 设置补齐
                if (!empty($completions)) {
                    $impl->setCompletions(...$completions);
                }

            } elseif ($impl instanceof AbstractComputeStatistician) {

                // 设置补齐
                if (!empty($completions)) {
                    $impl->setCompletions(...$completions);
                }

                // 获取依赖的字段
                $statisticians = $impl->getStatisticians();

                // 获取依赖字段
                $statisticianMap = [];
                foreach ($statisticians as $statistician => $statisticianImplClass) {
                    $statisticianMap[$statistician] = $this->getData($statisticianImplClass, $filters, $groupers, $completions);
                }
                if (!empty($statisticianMap)) {
                    $impl->setStatisticianData($statisticianMap);
                }
            }

            $this->cache[$implClass] = $impl->getData();
        }

        return $this->cache[$implClass];
    }

    // 首页渗透率
    private function getData1($startTime, $endTime, $date): array
    {

        // 进入首页次数
        $shouye = AccessLog::where('date', $date)
            ->where('pagePath', AccessLog::PAGE_MEMBER_SOUYE)
            ->group('ip')
            ->count();

        $daguansi = '';
        $jisuzixun = '';
        $zhaolvshi = '';
        $dianhua = '';
        $lvshizhuye = '';
        $xinwen = '';
        $rengong = '';
        $lvshirenzheng = '';
        $fenxiang = '';

        if ($shouye != 0) {

            $daguansi = AccessLog::where('date', $date)
                ->where('referer', AccessLog::PAGE_MEMBER_SOUYE)
                ->where('pagePath', AccessLog::PAGE_MEMBER_LAWSUIT_STEP1)
                ->group('ip')
                ->count();
            $daguansi = show_percentage($daguansi, $shouye, 1);

            $jisuzixun = AccessLog::where('date', $date)
                ->where('referer', AccessLog::PAGE_MEMBER_SOUYE)
                ->where('pagePath', AccessLog::PAGE_MEMBER_CHAT)
                ->group('ip')
                ->count();
            $jisuzixun = show_percentage($jisuzixun, $shouye, 1);

            $zhaolvshi = AccessLog::where('date', $date)
                ->where('referer', AccessLog::PAGE_MEMBER_SOUYE)
                ->where('pagePath', AccessLog::PAGE_MEMBER_ZHAOLVSHI)
                ->group('ip')
                ->count();
            $zhaolvshi = show_percentage($zhaolvshi, $shouye, 1);

            $dianhua = AccessLog::where('date', $date)
                ->where('referer', AccessLog::PAGE_MEMBER_SOUYE)
                ->where('pagePath', AccessLog::PAGE_MEMBER_CONSULTING_PHONE)
                ->group('ip')
                ->count();
            $dianhua = show_percentage($dianhua, $shouye, 1);

            $lvshizhuye = AccessLog::where('date', $date)
                ->where('referer', AccessLog::PAGE_MEMBER_SOUYE)
                ->where('pagePath', AccessLog::PAGE_MEMBER_LVSHIZHUYE)
                ->group('ip')
                ->count();
            $lvshizhuye = show_percentage($lvshizhuye, $shouye, 1);

            $xinwen = AccessLog::where('date', $date)
                ->where('referer', AccessLog::PAGE_MEMBER_SOUYE)
                ->where('pagePath', AccessLog::PAGE_MEMBER_REMENZIXUNXIANGQING)
                ->group('ip')
                ->count();
            $xinwen = show_percentage($xinwen, $shouye, 1);

            $lvshirenzheng = AccessLog::where('date', $date)
                ->where('referer', AccessLog::PAGE_MEMBER_SOUYE)
                ->where('pagePath', AccessLog::PAGE_MEMBER_LVSHIRENZHENG)
                ->group('ip')
                ->count();
            $lvshirenzheng = show_percentage($lvshirenzheng, $shouye, 1);

            $fenxiang = AccessLog::where('date', $date)
                ->where('referer', AccessLog::PAGE_MEMBER_SOUYE)
                ->where('pagePath', AccessLog::PAGE_MEMBER_SHARE)
                ->group('ip')
                ->count();
            $fenxiang = show_percentage($fenxiang, $shouye, 1);

        }

        return [
            'title' => '首页渗透率',
            'data' => [
                [
                    'title' => '首页进入打官司占比',
                    'value' => $daguansi,
                ],
                [
                    'title' => '首页进入极速咨询占比',
                    'value' => $jisuzixun,
                ],
                [
                    'title' => '首页进入找律师占比',
                    'value' => $zhaolvshi,
                ],
                [
                    'title' => '首页进入电话咨询占比',
                    'value' => $dianhua,
                ],
                [
                    'title' => '首页进入律师页占比',
                    'value' => $lvshizhuye,
                ],
                [
                    'title' => '首页进入新闻页占比',
                    'value' => $xinwen,
                ],
                [
                    'title' => '首页进入人工客服占比',
                    'value' => $rengong,
                ],
                [
                    'title' => '首页进入律师认证占比',
                    'value' => $lvshirenzheng,
                ],
                [
                    'title' => '首页进入公益分享占比',
                    'value' => $fenxiang,
                ],
            ]
        ];
    }

    // 找律师
    private function getData2($startTime, $endTime, $date): array
    {
        $uv = '';
        $wancheng = '';
        $fufei = '';

        if ($startTime < time()) {

            $uv = AccessLog::where('date', $date)
                ->where('pagePath', AccessLog::PAGE_MEMBER_ZHAOLVSHI)
                ->group('ip')
                ->count();

            // 问题数 成功提交问题的问题数（人数去重）
            $wentishu = Consulting::timeRange($startTime, $endTime, 'created', 'created')
                ->where('pagePath', AccessLog::PAGE_MEMBER_ZHAOLVSHI)
                ->where('isAsked', '1')
                ->group('memberId')
                ->count();

            // 付费问题数
            $fufeishu = Consulting::timeRange($startTime, $endTime, 'created', 'created')
                ->where('pagePath', AccessLog::PAGE_MEMBER_ZHAOLVSHI)
                ->where('consultingType', '1')
                ->whereIn('status', ['1', '2'])
                ->group('memberId')
                ->count();

            // 完成问题占比：成功提交问题的问题数（人数去重）/进该页面的UV
            $wancheng = show_percentage($wentishu, $uv, 1, '0%');

            // 找律师付费率 (付费占比） ：    提交问题后付费的人数/成功提交问题的问题数（人数去重）
            $fufei = show_percentage($fufeishu, $wentishu, 1, '0%');

        }

        return [
            'title' => '找律师',
            'data' => [
                [
                    'title' => '进入找律师UV',
                    'value' => $uv,
                ],
                [
                    'title' => '完成问题占比',
                    'value' => $wancheng,
                ],
                [
                    'title' => '付费占比',
                    'value' => $fufei,
                ],
            ]
        ];
    }

    // 极速咨询
    private function getData3($startTime, $endTime, $date): array
    {

        $uv = '';
        $wancheng = '';
        $fufei = '';

        if ($startTime < time()) {

            $uv = AccessLog::where('date', $date)
                ->where('pagePath', AccessLog::PAGE_MEMBER_CHAT)
                ->group('ip')
                ->count();

            // 问题数 成功提交问题的问题数（人数去重）
            $wentishu = Consulting::timeRange($startTime, $endTime, 'created', 'created')
                ->where('pagePath', AccessLog::PAGE_MEMBER_SOUYE)
                ->where('isAsked', '1')
                ->group('memberId')
                ->count();

            // 付费问题数
            $fufeishu = Consulting::timeRange($startTime, $endTime, 'created', 'created')
                ->where('pagePath', AccessLog::PAGE_MEMBER_SOUYE)
                ->where('consultingType', '1')
                ->whereIn('status', ['1', '2'])
                ->group('memberId')
                ->count();

            // 付费人数
            // $fufeishu = Trade::timeRange($startTime, $endTime, 'created', 'created')
            //     ->where('payStatus', Trade::PAID)
            //     ->consultingTrade()
            //     ->group('memberId')
            //     ->count();

            // 完成问题占比：成功提交问题的问题数（人数去重）/进该页面的UV
            $wancheng = show_percentage($wentishu, $uv, 1, '0%');

            // 找律师付费率 (付费占比） ：    提交问题后付费的人数/成功提交问题的问题数（人数去重）
            $fufei = show_percentage($fufeishu, $wentishu, 1, '0%');

        }

        return [
            'title' => '极速咨询',
            'data' => [
                [
                    'title' => '进入极速咨询UV',
                    'value' => $uv,
                ],
                [
                    'title' => '完成问题占比',
                    'value' => $wancheng,
                ],
                [
                    'title' => '付费占比',
                    'value' => $fufei,
                ],
            ]
        ];
    }

    // 电话咨询
    private function getData4($startTime, $endTime, $date): array
    {
        $uv = '';
        $wancheng = '';
        $fufei = '';

        if ($startTime < time()) {

            $uv = AccessLog::where('date', $date)
                ->where('pagePath', AccessLog::PAGE_MEMBER_CONSULTING_PHONE)
                ->group('ip')
                ->count();

            // 问题数 成功提交问题的问题数（人数去重）
            $wentishu = Consulting::timeRange($startTime, $endTime, 'created', 'created')
                ->where('pagePath', AccessLog::PAGE_MEMBER_CONSULTING_PHONE)
                ->where('isAsked', '1')
                ->group('memberId')
                ->count();

            // 付费问题数
            $fufeishu = Consulting::timeRange($startTime, $endTime, 'created', 'created')
                ->where('pagePath', AccessLog::PAGE_MEMBER_CONSULTING_PHONE)
                ->where('consultingType', '1')
                ->whereIn('status', ['1', '2'])
                ->group('memberId')
                ->count();

            // 付费人数
            // $fufeishu = Trade::timeRange($startTime, $endTime, 'created', 'created')
            //     ->where('payStatus', Trade::PAID)
            //     ->consultingTrade()
            //     ->group('memberId')
            //     ->count();

            // 完成问题占比：成功提交问题的问题数（人数去重）/进该页面的UV
            $wancheng = show_percentage($wentishu, $uv, 1, '0%');

            // 找律师付费率 (付费占比） ：    提交问题后付费的人数/成功提交问题的问题数（人数去重）
            $fufei = show_percentage($fufeishu, $wentishu, 1, '0%');

        }

        return [
            'title' => '电话咨询',
            'data' => [
                [
                    'title' => '进入电话咨询UV',
                    'value' => $uv,
                ],
                [
                    'title' => '完成问题占比',
                    'value' => $wancheng,
                ],
                [
                    'title' => '付费占比',
                    'value' => $fufei,
                ],
            ]
        ];
    }

    // 打官司（三部曲）
    private function getData5($startTime, $endTime, $date): array
    {
        $uv = '';
        $buzou1 = '';
        $buzou2 = '';
        $buzou3 = '';
        $fufei = '';
        if ($startTime < time()) {

            // 小程序 + h5
            $uv = AccessLog::where('date', $date)
                ->whereIn('pagePath', [AccessLog::PAGE_MEMBER_LAWSUIT_STEP1,
                    AccessLog::PAGE_H5_LAWSUIT_ENTRY1,
                    AccessLog::PAGE_H5_LAWSUIT_ENTRY2])
                ->group('ip')
                ->count();

            //完成第1步
            $buzou1 = Lawsuit::where('step', '>=', 1)->count();
            $buzou1 = show_percentage($buzou1, $uv, 1, '0%');

            //完成第2步
            $buzou2 = Lawsuit::where('step', '>=', 2)->count();
            $buzou2 = show_percentage($buzou2, $uv, 1, '0%');

            //完成第3步
            $buzou3 = Lawsuit::where('step', '>=', 3)->count();
            $buzou3 = show_percentage($buzou3, $uv, 1, '0%');

            // 问题数 成功提交问题的问题数（人数去重）
            $wentishu = Consulting::timeRange($startTime, $endTime, 'created', 'created')
                ->where('pagePath', AccessLog::PAGE_MEMBER_LAWSUIT_STEP1)
                ->where('isAsked', '1')
                ->group('memberId')
                ->count();

            // 付费问题数
            $fufeishu = Consulting::timeRange($startTime, $endTime, 'created', 'created')
                ->where('pagePath', AccessLog::PAGE_MEMBER_LAWSUIT_STEP1)
                ->where('consultingType', '1')
                ->whereIn('status', ['1', '2'])
                ->group('memberId')
                ->count();
            //付费占比
            $fufei = show_percentage($fufeishu, $wentishu, 1, '0%');
        }

        return [
            'title' => '打官司（三部曲）',
            'data' => [
                [
                    'title' => '进入打官司UV',
                    'value' => $uv,
                ],
                [
                    'title' => '完成第一步占比',
                    'value' => $buzou1,
                ],
                [
                    'title' => '完成第二步占比',
                    'value' => $buzou2,
                ],
                [
                    'title' => '完成第三步占比',
                    'value' => $buzou3,
                ],
                [
                    'title' => '付费占比',
                    'value' => $fufei,
                ],
            ]
        ];
    }

    // 律师
    private function getData6($startTime, $endTime, $date): array
    {
        $uv = '';
        $zixun = '';
        $shouye = '';
        $fufei = '';

        if ($startTime < time()) {

            $uv = AccessLog::where('date', $date)
                ->where('pagePath', AccessLog::PAGE_MEMBER_LVSHI)
                ->group('ip')
                ->count();

            // 进入律师主页数
            $shouyeshu = AccessLog::where('date', $date)
                ->where('referer', AccessLog::PAGE_MEMBER_LVSHI)
                ->where('pagePath', AccessLog::PAGE_MEMBER_LVSHIZHUYE)
                ->group('ip')
                ->count();

            // 问题数 成功提交问题的问题数（人数去重）
            $wentishu = Consulting::timeRange($startTime, $endTime, 'created', 'created')
                ->whereIn('pagePath', [AccessLog::PAGE_MEMBER_LVSHI, AccessLog::PAGE_MEMBER_LVSHIZHUYE])
                ->where('isAsked', '1')
                ->group('memberId')
                ->count();

            // 付费问题数
            $fufeishu = Consulting::timeRange($startTime, $endTime, 'created', 'created')
                ->whereIn('pagePath', [AccessLog::PAGE_MEMBER_LVSHI, AccessLog::PAGE_MEMBER_LVSHIZHUYE])
                ->where('consultingType', '1')
                ->whereIn('status', ['1', '2'])
                ->group('memberId')
                ->count();

            $zixun = show_percentage($zixun, $uv, 1, '0%');
            $shouye = show_percentage($shouyeshu, $uv, 1, '0%');
            $fufei = show_percentage($fufeishu, $wentishu, 1, '0%');

        }

        return [
            'title' => '律师',
            'data' => [
                [
                    'title' => '进入律师列表UV',
                    'value' => $uv,
                ],
                [
                    'title' => '咨询律师占比',
                    'value' => $zixun,
                ],
                [
                    'title' => '进入律师首页占比',
                    'value' => $shouye,
                ],
                [
                    'title' => '付费占比',
                    'value' => $fufei,
                ],
            ]
        ];
    }

    // 短信H5页面
    private function getData8($startTime, $endTime, $date): array
    {
        $pv0 = '';
        $uv0 = '';
        $pv1 = '';
        $uv1 = '';
        $pv2 = '';
        $uv2 = '';

        if ($startTime < time()) {

            $pv0 = AccessLog::where('date', $date)
                ->where('pagePath', AccessLog::PAGE_H5_SMS1)
                ->count();

            $uv0 = AccessLog::where('date', $date)
                ->where('pagePath', AccessLog::PAGE_H5_SMS1)
                ->group('ip')
                ->count();


            $pv1 = AccessLog::where('date', $date)
                ->where('pagePath', AccessLog::PAGE_H5_SMS2)
                ->count();

            $uv1 = AccessLog::where('date', $date)
                ->where('pagePath', AccessLog::PAGE_H5_SMS2)
                ->group('ip')
                ->count();

            $pv2 = AccessLog::where('date', $date)
                ->where('pagePath', AccessLog::PAGE_H5_SMS3)
                ->count();

            $uv2 = AccessLog::where('date', $date)
                ->where('pagePath', AccessLog::PAGE_H5_SMS3)
                ->group('ip')
                ->count();
        }

        return [
            'title' => '短信H5页面',
            'data' => [
                [
                    'title' => '未支付页面PV',
                    'value' => $pv0,
                ],
                [
                    'title' => '未支付页面UV',
                    'value' => $uv0,
                ],
                [
                    'title' => '已回复页面PV',
                    'value' => $pv1,
                ],
                [
                    'title' => '已回复页面UV',
                    'value' => $uv1,
                ],
                [
                    'title' => '订单待支付页面PV',
                    'value' => $pv2,
                ],
                [
                    'title' => '订单待支付页面UV',
                    'value' => $uv2,
                ],
            ]
        ];
    }

    // 核心业务
    private function getData7($startTime, $endTime, $date): array
    {

        $free_count = '';
        $anyuan_count = '';
        $fufei = '';
        $zhucezhifu = '';

        if ($startTime < time()) {

            $free_count = Consulting::timeRange($startTime, $endTime, 'created', 'created')
                ->where('consultingType', '0')
                ->count();

            $anyuan_count = LawCase::timeRange($startTime, $endTime, 'created', 'created')
                ->count();

            $fufei = Trade::timeRange($startTime, $endTime, 'created', 'created')
                ->where('payStatus', Trade::PAID)
                ->consultingTrade()
                ->count();

            // 支付成功订单数
            $pay_success_count = Trade::timeRange($startTime, $endTime, 'created', 'created')
                ->consultingTrade()
                ->where('payStatus', Trade::PAID)
                ->count();

            // 新增用户（注册数）
            $new_member_count = Member::timeRange($startTime, $endTime, 'created', 'created')->count();

            // 注册支付率
            $zhucezhifu = show_percentage($pay_success_count, $new_member_count, 1, '0%');

        }

        return [
            'title' => '核心业务',
            'data' => [
                [
                    'title' => '免费咨询数',
                    'value' => $free_count,
                ],
                [
                    'title' => '案源总数',
                    'value' => $anyuan_count,
                ],
                [
                    'title' => '付费总数',
                    'value' => $fufei,
                ],
                [
                    'title' => '注册支付率',
                    'value' => $zhucezhifu,
                ],
            ]
        ];
    }

    // H5落地页 -链路A
    private function getData9($startTime, $endTime, $date): array
    {
        $pv = '';
        $uv = '';
        $new_member_count = '';

        $chain = 'h5-landing1-A';

        if ($startTime < time()) {

            $pv = AccessLog::where('date', $date)
                ->where('chain', $chain)
                ->where('pagePath', AccessLog::PAGE_H5_LANDING1_ENTRY1)
                ->count();

            $uv = AccessLog::where('date', $date)
                ->where('chain', $chain)
                ->where('pagePath', AccessLog::PAGE_H5_LANDING1_ENTRY1)
                ->group('ip')
                ->count();

            //   新增用户（注册数）
            $new_member_count = Member::timeRange($startTime, $endTime, 'created', 'created')
                ->where('chain', $chain)
                ->where('channel', 10)
                ->count();

        }

        return [
            'title' => '落地页A',
            'data' => [
                [
                    'title' => 'PV',
                    'value' => $pv,
                ],
                [
                    'title' => 'UV',
                    'value' => $uv,
                ],
                [
                    'title' => '注册数',
                    'value' => $new_member_count,
                ],
            ]
        ];
    }

    // H5落地页 -链路B
    private function getData9_1($startTime, $endTime, $date): array
    {
        $pv = '';
        $uv = '';
        $new_member_count = '';

        $chain = 'h5-landing1-B';

        if ($startTime < time()) {

            $pv = AccessLog::where('date', $date)
                ->where('chain', $chain)
                ->where('pagePath', AccessLog::PAGE_H5_LANDING1_ENTRY2)
                ->count();

            $uv = AccessLog::where('date', $date)
                ->where('chain', $chain)
                ->where('pagePath', AccessLog::PAGE_H5_LANDING1_ENTRY2)
                ->group('ip')
                ->count();

            //   新增用户（注册数）
            $new_member_count = Member::timeRange($startTime, $endTime, 'created', 'created')
                ->where('chain', $chain)
                ->where('channel', 10)
                ->count();

        }

        return [
            'title' => '落地页B',
            'data' => [
                [
                    'title' => 'PV',
                    'value' => $pv,
                ],
                [
                    'title' => 'UV',
                    'value' => $uv,
                ],
                [
                    'title' => '注册数',
                    'value' => $new_member_count,
                ],
            ]
        ];
    }

}
